#include <iostream>
#include <unistd.h>
#include <cstring>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#define MAX_SIZE 4096
#define PATH_NAME "."
#define PROC_ID 216
using namespace std;
// 获取key值
key_t getKey()
{
    key_t key = ftok(PATH_NAME, PROC_ID);
    if (key == -1)
    {
        cerr << "getKey:" << strerror(errno) << endl;
    }
    return key;
}
// 获取shmId
int getShmHelper(int flag)
{
    key_t key = getKey();
    umask(0);
    int ret = shmget(key, MAX_SIZE, flag);
    if (ret == -1)
    {
        cerr << "getShmHelper:" << strerror(errno) << endl;
        exit(1);
    }
    return ret;
}
// 创建Shm
int createShm()
{
    return getShmHelper(IPC_CREAT | IPC_EXCL | 0666);
}
// 获取Shm
int getShm()
{
    return getShmHelper(IPC_CREAT);
}
// 获取Shm地址
void *attachShm(int shmId)
{
    void *mem = shmat(shmId, nullptr, 0);
    if ((long)mem == -1)
    {
        cerr << "attachShm:" << strerror(errno) << endl;
        exit(3);
    }
    return mem;
}
// 去关联
void detachShm(void *mem)
{
    int ret = shmdt(mem);
    if (ret == -1)
    {
        std::cerr << "shmdt: " << errno << strerror(errno) << std::endl;
        exit(4);
    }
}
// 清理Shm
void removeShm(int shmId)
{
    int ret = shmctl(shmId, IPC_RMID, nullptr);
    if (ret == -1)
    {
        cerr << "removeShm:" << strerror(errno) << endl;
        exit(2);
    }
}